//
//  String+AG.swift
//  ASW
//
//  Created by zhuxuhong on 2020/11/23.
//

import UIKit

extension String {
    static var bw_uuid: String {
        return UUID().uuidString
    }
    
    public static func typeName(of any: Any) -> String {
        return "\(type(of: any))"
    }
}

extension Optional where Wrapped == String {
    public var length: Int {
        guard let s = self else {
            return 0
        }
        return s.count
    }
    public var isEmpty: Bool {
        return length == 0
    }
}

extension NSAttributedString {
    public func bw_boundingWidth(byFixedHeight h: CGFloat, attributes: [NSAttributedString.Key : Any]? = nil) -> CGFloat {
        let v = boundingRect(with: .init(width: .infinity, height: h), options: [.usesFontLeading,.usesLineFragmentOrigin], context: nil).size.width
        return v
    }
    public func bw_boundingHeight(byFixedWidth w: CGFloat, attributes: [NSAttributedString.Key : Any]? = nil) -> CGFloat {
        let v = boundingRect(with: .init(width: w, height: .infinity), options: [.usesFontLeading,.usesLineFragmentOrigin], context: nil).size.height
        return v
    }
}

extension String {
    public func bw_boundingWidth(byFixedHeight h: CGFloat, attributes: [NSAttributedString.Key : Any]? = nil) -> CGFloat {
        let v = (self as NSString).boundingRect(with: .init(width: .infinity, height: h), options: [.usesFontLeading,.usesLineFragmentOrigin], attributes: attributes, context: nil).size.width
        return v
    }
    public func bw_boundingHeight(byFixedWidth w: CGFloat, attributes: [NSAttributedString.Key : Any]? = nil) -> CGFloat {
        let v = (self as NSString).boundingRect(with: .init(width: w, height: .infinity), options: [.usesFontLeading,.usesLineFragmentOrigin], attributes: attributes, context: nil).size.height
        return v
    }
}

extension String {
    public func bw_unsatisfy(
        minCount: Int = 1,
        maxCount: Int,
        tips: String = ""
    ) -> String? {
        if count < minCount {
            return "\(tips)至少需要\(minCount)个字符~"
        }
        if count > maxCount {
            return "\(tips)不能超过\(maxCount)个字符~"
        }
        return nil
    }
}

extension String {
    public var bw_urlQueryAllowed: Self? {
        return addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
    }
    
    public func bw_nsRange(from range: Range<Index>) -> NSRange {
        return .init(range, in: self)
    }
    
    /*
    public var bw_cnPhoneNumberEncrypted: String {
        guard let p = substring(to: 3),
              let s = substring(from: 7) else {
            return self
        }
        return "\(p)****\(s)"
    }*/
}

extension String{
    public func bw_replaces(of olds: String..., by new: String) -> String {
        var str = self
        olds.forEach{
            str = str.replacingOccurrences(of: $0, with: new)
        }
        return str
    }
    public func bw_replaces(of olds: String..., with news: String...) -> String {
        var str = self
        for (i,o) in olds.enumerated() {
            if i < news.count {
                str = str.replacingOccurrences(of: o, with: news[i])
            }
        }
        return str
    }
}

extension String {
    public var bw_verticaled: String {
        var strs: [String] = []
        for i in 0..<count {
            let s = index(startIndex, offsetBy: i)
            let e = index(startIndex, offsetBy: i+1)
            strs.append(substring(with: s..<e))
        }
        return strs.joined(separator: "\n")
    }
}


extension String {
    /*
    public func bw_toDate(
        components: DateComponentSet = .full,
        dateJoinTag: DateFormatter.DateJoinTag = .line1,
        timeJoinTag: DateFormatter.TimeJoinTag = .comma
    ) -> String {
        let date = bw_formattedDateString(components: components, joinTag: dateJoinTag)
        let time = bw_formattedTimeString(components: components, joinTag: timeJoinTag)
        return date + " " + time
    }
    
    var dateSimplified: String {
        let now = Date()
        guard let date = toDate() else {
            return self
        }
        if now.minutesSince(date) <= 1 {
            return "刚刚"
        }
        let minutes = now.minutesSince(date)
        if minutes <= 60 {
            return "\(Int(minutes))分钟前"
        }
        if date.isInToday {
            return "\(Int(now.hoursSince(date)))小时前"
        }
        if date.isInYesterday {
            return "昨天 \(date.toString(style: .hourMinutes))"
        }
        if date.isInCurrentWeek {
            return "\(Int(now.daysSince(date)))天前"
        }
        if date.isInCurrentYear {
            return date.toString(style: .monthDays)
        }
        return date.toString(style: .yearMonthDays)
    }*/
}
